package GUI;

import IA.*;
import Simulation.CustomerSimulator;
import Simulation.KitchenSimulator;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.GroupLayout.Alignment;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import system_interface.SystemInterface;

// @author Rob Leister rleist1@students.towson.edu
public class SimulatorGUI extends javax.swing.JFrame {

    private JLabel jLabel1, jLabel2, jLabel3, jLabel4, jLabel5, jLabel6, jLabel8;
    private JSlider jSlider1, jSlider2, jSlider3, jSlider4, jSlider5, jSlider7;
    private JFormattedTextField jReductField;
    private JButton jButton1, jButton2;
    private JToggleButton jToggleButton1;
    private JRadioButton chronoRadButton, highestRadButton, lowestRadButton, similarRadButton;
    SystemInterface si;
    KitchenSimulator kitchen;
    CustomerSimulator hostess;
    InformationAggregator ia;
    List<ManagersGUI> mangui = new ArrayList<ManagersGUI>();
    newManagerGUI mgui;
    private final int DEFAULT_NUM_SERVERS = 5;

    public void update() {
        jLabel1.setText("Number of Tables: " + jSlider1.getValue());
        jLabel2.setText("Minimum Eat Time: " + hostess.getEatTime());
        jLabel3.setText("Customer Arrival Delay: " + hostess.getArrivalDelay());
        jLabel4.setText("Grill Capacity: " + kitchen.getGrillCapacity());
        jLabel5.setText("Clock Rate: " + SystemClock.getInstance().getTimeScale());
        jLabel8.setText("Number of Servers: " + ia.getServerCollection().getNumServers());
        this.repaint();
    }

    public SimulatorGUI() {
        initComponents();
    }

    public SimulatorGUI(SystemInterface s, CustomerSimulator m, KitchenSimulator k, InformationAggregator ia) {
        initComponents();
        this.ia = ia;
        si = s;
        hostess = m;
        kitchen = k;
        ia.getServerCollection().setNumServers(DEFAULT_NUM_SERVERS, k.getObservableInstance());
        jSlider1.setValue(Integer.parseInt(si.getNumberOfTables()));
        jSlider2.setValue(hostess.getEatTime());
        jSlider3.setValue(hostess.getArrivalDelay());
        jSlider4.setValue(kitchen.getGrillCapacity());
        jSlider5.setValue(SystemClock.getInstance().getTimeScale());
        jSlider7.setValue(ia.getServerCollection().getNumServers());
        jReductField.setValue(kitchen.getTimeReductionFactor());
        ActionListener refresh = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                update();
            }
        };
        new javax.swing.Timer(100, refresh).start();
        mgui = new newManagerGUI(si, kitchen, hostess);
        mgui.setLocation(400,0);
        mgui.setVisible(true);
    } // end SimulationGUI(si) constructor

    private void initComponents() {
        jLabel1 = new JLabel("Number of Tables");
        jLabel2 = new JLabel("Eat Time");
        jLabel3 = new JLabel("Customer Arrival Delay");
        jLabel4 = new JLabel("Grill Capacity");
        jLabel5 = new JLabel("Clock Rate");
        jLabel6 = new JLabel("Reduction Factor");
        jLabel8 = new JLabel("Number of Servers");
        jSlider1 = new JSlider(1, 20, 10);
        jSlider2 = new JSlider(1, 100, 20);
        jSlider3 = new JSlider(1, 50, 10);
        jSlider4 = new JSlider(1, 50, 5);
        jSlider5 = new JSlider(1, 600, 500);
        jSlider7 = new JSlider(1, 50, 5);
        jToggleButton1 = new JToggleButton("Start/Stop");
        jButton1 = new JButton("Add Manager GUI");
        jButton2 = new JButton("Add Four in One GUI");
        jReductField = new JFormattedTextField();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Simulation Control");
        setAlwaysOnTop(true);
        chronoRadButton = new JRadioButton("Chronological");
        highestRadButton = new JRadioButton("Highest");
        lowestRadButton = new JRadioButton("Lowest");
        similarRadButton = new JRadioButton("Similar");

        jSlider1.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                ia.getTableCollection().setTotalNumberOfTables(jSlider1.getValue());
            }
        });
        jButton1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                mangui.add(new ManagersGUI(si, hostess, kitchen));
                mangui.get(mangui.size() - 1).setVisible(true);
            }// end override
        });// end JButton1

        jButton2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                mgui = new newManagerGUI(si, kitchen, hostess);
                mgui.setLocation(400,0);
                mgui.setVisible(true);
            }// end override
        });// end JButton2

        jReductField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Double d = Double.parseDouble(jReductField.getText());
                kitchen.setTimeReductionFactor(d);
            }// end override
        });// end jReductField

        jSlider1.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent evt) {
                Integer red = jSlider1.getValue();
                String str = red.toString();
                si.setNumberOfTables(str);
            } // end stateChanged
        }); //end JSlider1 addChangeListener

        jSlider2.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent evt) {
                hostess.setEatTime(jSlider2.getValue());
            } // end stateChanged
        });  //end JSlider2 addChangeListener

        jSlider3.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent evt) {
                hostess.setArrivalDelay((Integer) jSlider3.getValue());
            } // end stateChanged
        });  //end JSlider3 addChangeListener

        jSlider4.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                kitchen.setGrillCapacity((Integer) jSlider4.getValue());
            } // end stateChanged
        });  //end JSlider4 addChangeListener

        jSlider5.addChangeListener(
                new ChangeListener() {

                    @Override
                    public void stateChanged(ChangeEvent evt) {
                        SystemClock.getInstance().setTimeScale((Integer) jSlider5.getValue());
                    } // end stateChanged
                });  //end JSlider5 addChangeListener


        jSlider7.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent evt) {
                ia.getServerCollection().setNumServers(jSlider7.getValue(), kitchen.getObservableInstance());
            } // end stateChanged
        });  //end JSlider7 addChangeListener

        jToggleButton1.addActionListener(
                new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        if (SystemClock.getInstance().isRunning()) {
                            SystemClock.getInstance().setRunning(false);
                        } else {
                            SystemClock.getInstance().setRunning(true);
                        }
                    }// end actionPerformed
                }); // end JToggleButton1 addActionListener
        chronoRadButton.setSelected(true);
        chronoRadButton.setActionCommand("Chronological");
        highestRadButton.setActionCommand("Highest");
        lowestRadButton.setActionCommand("Lowest");
        similarRadButton.setActionCommand("Similar");
        chronoRadButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                kitchen.setCookStrategy(new ChronologicalCookStrategy());
            }// end action performed
        });
        highestRadButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                kitchen.setCookStrategy(new HighestPrepTimeCookStrategy());
            }// end action performed
        });
        lowestRadButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                kitchen.setCookStrategy(new LowestPrepTimeCookStrategy());
            }// end action performed
        });
        similarRadButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                kitchen.setCookStrategy(new SimilarItemCookStrategy());
            }// end action performed
        });

        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(chronoRadButton);
        buttonGroup.add(highestRadButton);
        buttonGroup.add(lowestRadButton);
        buttonGroup.add(similarRadButton);
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        Alignment trailing = GroupLayout.Alignment.TRAILING;
        Alignment leading = GroupLayout.Alignment.LEADING;
        layout.setAutoCreateGaps(true);
        layout.setHorizontalGroup(
                layout.createSequentialGroup() //
                .addGap(20)//
                .addGroup(layout.createParallelGroup(leading, true) //
                .addGroup(layout.createSequentialGroup() //
                .addGroup(layout.createParallelGroup(leading, true) //
                .addComponent(jLabel4)// 
                .addComponent(jLabel8)// 
                .addComponent(jLabel3)//
                .addComponent(jLabel2)//
                .addComponent(jLabel1)//
                .addComponent(jLabel5) //
                .addComponent(jLabel6) //
                .addComponent(jSlider1, leading, 10, 100, 150) //
                .addComponent(jSlider7, leading, 10, 100, 150) //
                .addComponent(jSlider2, leading, 10, 100, 150) //
                .addComponent(jSlider3, leading, 10, 100, 150) //
                .addComponent(jSlider4, leading, 10, 100, 150) //
                .addComponent(jSlider5, leading, 10, 90, 150) //
                .addGap(20) //
                )// end Label Group
                .addGroup(layout.createParallelGroup(leading) //
                .addComponent(jReductField, leading, 40, 45, 45) // //
                .addGap(20)//
                ) // End Slider Group
                .addGroup(layout.createParallelGroup(trailing) //
                .addComponent(chronoRadButton)//
                .addComponent(highestRadButton)//
                .addComponent(lowestRadButton)//
                .addComponent(similarRadButton)//
                ) // End Radio Buttons
                ) // End Sequential
                .addGap(20)//
                .addComponent(jButton2, leading, GroupLayout.DEFAULT_SIZE, 50, Short.MAX_VALUE) //
                .addComponent(jButton1, leading, GroupLayout.DEFAULT_SIZE, 50, Short.MAX_VALUE) //
                .addGap(20)//
                .addComponent(jToggleButton1, leading, GroupLayout.DEFAULT_SIZE, 50, Short.MAX_VALUE) //
                ).addGap(20)//
                ); //

        layout.setVerticalGroup(
                layout.createParallelGroup(leading) //
                .addGroup(layout.createSequentialGroup() //
                .addContainerGap() //
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) //
                .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)) //
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) //
                .addComponent(jLabel8, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jSlider7, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(highestRadButton)//
                ) // 
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) //
                .addComponent(jLabel2, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jSlider2, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(lowestRadButton)//
                ) // 
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) //
                .addComponent(similarRadButton)//
                ) // 
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) // 
                .addComponent(jLabel3, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jSlider3, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(chronoRadButton) //
                ) //
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) //
                .addComponent(jLabel4, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jSlider4, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)//
                ) // 
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) //
                .addComponent(jLabel5, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) // 
                .addComponent(jSlider5, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)//
                ) // 
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) //
                .addComponent(jLabel6, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) // 
                .addComponent(jReductField, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)//
                ) // 
                .addComponent(jButton2, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jButton1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jSlider1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addComponent(jToggleButton1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) //
                .addContainerGap() //
                )// end sequential
                );

        layout.linkSize(SwingConstants.VERTICAL,
                new java.awt.Component[]{jLabel1, jSlider1, chronoRadButton
                });
        layout.linkSize(SwingConstants.VERTICAL,
                new java.awt.Component[]{jLabel8, jSlider7, highestRadButton
                });
        layout.linkSize(SwingConstants.VERTICAL,
                new java.awt.Component[]{jLabel2, jSlider2, lowestRadButton
                });
        layout.linkSize(SwingConstants.VERTICAL,
                new java.awt.Component[]{jLabel3, jSlider3, similarRadButton
                });
        layout.linkSize(SwingConstants.VERTICAL,
                new java.awt.Component[]{jLabel4, jSlider4
                });
        layout.linkSize(SwingConstants.VERTICAL,
                new java.awt.Component[]{jLabel5, jSlider5
                });

        pack();
    } // end init components

    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUI.SimulatorGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUI.SimulatorGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUI.SimulatorGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUI.SimulatorGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new GUI.SimulatorGUI().setVisible(true);
            }
        });
    }
} // End Class SimulatorGUI
